
#include <BStyle>
#include <BIcon>
#include <BPainter>
#include <BMouseEvent>

#include "ImageLayer.h"
#include "PixmapArea.h"
#include "ColorReplacer.h"

ColorReplacer::ColorReplacer() : Operation("Color Picker")
{
	_dirtyPoints = true;
}
ColorReplacer::~ColorReplacer()
{

}

void ColorReplacer::setMatchColor(BColor color)
{
	if (_matchColor != color)
	{
		_matchColor = color;
		_dirtyPoints = true;
		this->fresh();
	}
}
void ColorReplacer::setMatchTolerance(int tolerance)
{
	if (_matchTolerance != tolerance)
	{
		_matchTolerance = tolerance;
		_dirtyPoints = true;
		this->fresh();
	}
}
void ColorReplacer::setTargetColor(BColor color)
{
	if (_targetColor != color)
	{
		_targetColor = color;
	}
}
void ColorReplacer::setOnlyConstituency(bool constituency)
{
	if (_onlyConstituency != constituency)
	{
		_onlyConstituency = constituency;
	}
}

void ColorReplacer::showMatchedGraph()
{

}
void ColorReplacer::hideMatchedGraph()
{

}

void ColorReplacer::replace()
{
	for (auto it = _layerPointsMap.begin(); it.valid(); ++it)
	{
		ImageLayer* layer = it.key();
		BImage* image = layer->image();
		const BPointArray& points = it.value();
		for (int i = 0; i < points.size(); i++)
		{
			BPoint pos = points[i];
			image->setPixelColor(pos.x(), pos.y(), _targetColor);
		}
		layer->fresh();
		image->dirty();
	}
	_layerPointsMap.empty();
	this->fresh();
}

void ColorReplacer::attached(BWidget* widget)
{
	Operation::attached(widget);
}
void ColorReplacer::detached(BWidget* widget)
{
	Operation::detached(widget);
}

void ColorReplacer::paint(BPainter& painter)
{
	PixmapArea* pixmapArea = this->pixmapArea();
	painter.setColor(255, 0, 0);
	painter.setPointSize(3);
	for (auto it = _layerPointsMap.begin(); it.valid(); ++it)
	{
		ImageLayer* layer = it.key();
		const BPoint& pos = layer->pos();
		const BPointArray& points = it.value();
		for (int i = 0; i < points.size(); i++)
		{
			BPoint point = pixmapArea->mapFromPixmap(pos + points[i]);
			painter.drawPoint(point);
		}
	}
}

void ColorReplacer::freshEvent(const BEvent& event)
{
	if (_dirtyPoints)
	{
		BPixmap* pixmap = this->pixmap();
		_layerPointsMap.reset();
		for (int i = 0; i < pixmap->widgetCount(); i++)
		{
			ImageLayer* layer = (ImageLayer*)pixmap->widget(i);
			if (!layer->visible())
				continue;
			BPointArray& points = _layerPointsMap[layer];
			BImage* image = layer->image();
			BColor color = _matchColor;
			for (int y = 0; y < image->height(); y++)
			{
				for (int x = 0; x < image->width(); x++)
				{
					if (!image->pixelColor(x, y, color))
						continue;
					BColor c = _matchColor - color;
					BByte D = bMax(bMax(c.r(), c.g()), bMax(c.b(), c.a()));
					if (D > _matchTolerance)
						continue;
					points.append(BPoint(x, y));
				}
			}
			if (points.empty())
			{
				_layerPointsMap.remove(layer);
			}
		}
		emit("pixels-catched", _layerPointsMap.size());
		_dirtyPoints = false;
	}
}

bool ColorReplacer::focusEvent(const BEvent& event)
{
	return false;
}
bool ColorReplacer::keyDownEvent(const BKeyEvent& keyEvent)
{
	return false;
}
bool ColorReplacer::keyUpEvent(const BKeyEvent& keyEvent)
{
	return false;
}

bool ColorReplacer::mouseEnterEvent(const BMouseEvent& mouseEvent)
{
	return false;
}
bool ColorReplacer::mouseLeaveEvent(const BMouseEvent& mouseEvent)
{
	return false;
}
bool ColorReplacer::mousePressEvent(const BMouseEvent& mouseEvent)
{
	return false;
}
bool ColorReplacer::mouseReleaseEvent(const BMouseEvent& mouseEvent)
{
	return false;
}
bool ColorReplacer::mouseMoveEvent(const BMouseEvent& mouseEvent)
{
	return false;
}
